package com.ckzp.jfinal.system.util;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.ckzp.core.util.StringUtil;
import com.ckzp.jfinal.form.FormData;
import com.ckzp.jfinal.interceptor.AuthMenu;
import com.ckzp.jfinal.system.cache.SysMenuCache;
import com.ckzp.jfinal.system.cache.SysRoleCache;
import com.ckzp.jfinal.system.cache.SysUserCache;
import com.ckzp.jfinal.system.model.SysActivity;
import com.ckzp.jfinal.system.model.SysMenu;
import com.ckzp.jfinal.plugins.tree.TreeNode;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 51594 on 2022/7/27.
 */
public class SysMenuUtil {

    public static SysMenuUtil n() {
        return new SysMenuUtil();
    }

    /**
     * @param am
     */
    public AuthMenu saveSysMenu(AuthMenu am) {
        am.setMenu_role(StringUtil.replace(am.getMenu_role(), ",", "|"));
        SysMenu menu = SysMenu.dao.findFirst("select * from sys_menu where menu_path=?", am.getMenu_path());
        if (menu == null) {
            new SysMenu()
                    .set("pmenu_id", 0)
                    .set("menu_name", am.getMenu_name())
                    .set("menu_type", 3)
                    .set("menu_path", am.getMenu_path())
                    .set("menu_role", am.getMenu_role())
                    .save();
        }
        return am;
    }


    /**
     * 根据菜单信息重置上层菜单权限
     *
     * @param menu_id
     */
    public void reloadMenuRoleByChild(int menu_id) {
        SysMenu menu = SysMenu.dao.findById(menu_id);
        //仅一级和二级菜单重置
        if (menu != null && menu.mod.getInt("menu_grade", 0) < 3) {
            String[] roles = getChildRole(menu);
            menu.set("menu_role", roles[0]).set("menu_role_name", SysRoleCache.transRoleName(roles[0]))
                    .set("menu_user", roles[1]).set("menu_user_name", SysUserCache.transUserName(roles[1])).update();
            if (menu.mod.getInt("menu_grade", 0) == 2) {
                int pmenu_id = menu.mod.getInt("pmenu_id", 0);
                if (pmenu_id != 0) {
                    SysMenu menu1 = SysMenu.dao.findById(pmenu_id);
                    if (menu1 != null) {
                        roles = getChildRole(menu1);
                        menu1.set("menu_role", roles[0]).set("menu_role_name", SysRoleCache.transRoleName(roles[0]))
                                .set("menu_user", roles[1]).set("menu_user_name", SysUserCache.transUserName(roles[1])).update();
                    }
                }
            }
        }

    }

    /**
     * @param menu
     * @return
     */
    private String[] getChildRole(SysMenu menu) {
        int menu_id = menu.mod.getInt("menu_id", 0);
        String roleid = "|", userid = "|";
        List<SysMenu> clist = SysMenu.dao.find("select * from sys_menu where pmenu_id=?", menu_id);
        for (SysMenu sm : clist) {
            String[] roles = StringUtil.split(sm.mod.getStr("menu_role"), "|");
            String[] users = StringUtil.split(sm.mod.getStr("menu_user"), "|");
            for (String role : roles) {
                if (role != null && role.length() > 0 && roleid.indexOf("|" + role + "|") == -1) {
                    roleid += role + "|";
                }
            }
            for (String user : users) {
                if (user != null && user.length() > 0 && userid.indexOf("|" + user + "|") == -1) {
                    userid += user + "|";
                }
            }
        }
        return new String[]{roleid, userid};
    }


    /**
     * 取得菜单树数据
     */
    public FormData getMenuTreeData() {
        return getMenuTreeData(null);
    }

    /**
     * 取得菜单树数据
     */
    public FormData getMenuTreeData(String role_id) {
        FormData fd = FormData.dao();
        /////////////////////////////////////////
        List firstlist = SysMenuCache.getFirstMenuList();
        List treelist = new ArrayList();

        for (int k = 0; k < firstlist.size(); k++) {
            SysMenu first = (SysMenu) firstlist.get(k);
            int menu_id = first.mod.getInt("menu_id");
            String menu_name = first.mod.getStr("menu_name");
            String menu_role = "|" + first.mod.getStr("menu_role") + "|";
            List<SysMenu> seclist = SysMenuCache.getSecondMenuList(menu_id);
            String titles = menu_name;

            TreeNode node1 = TreeNode.newNode("first_" + menu_id).setTitle("<span class=\"menufirst\">" + menu_name + "</span>").addDatas("grade", 1)
                    .addDatas("titles", titles).addDatas("menuid", menu_id).setTurn(true).setSpread(true);
            node1.setChecked(false);
            if (role_id != null && menu_role.indexOf("|" + role_id + "|") > -1) {
                //  node1.setChecked(true);
            }
            if (k == 0) node1.setSpread(true);
            for (int m = 0; m < seclist.size(); m++) {
                SysMenu second = (SysMenu) seclist.get(m);
                int menu2_id = second.mod.getInt("menu_id");
                String menu2_role = "|" + second.mod.getStr("menu_role") + "|";
                String menu2_name = second.mod.getStr("menu_name");
                titles = menu_name + " / " + menu2_name;
                if (fd.data.isEmpty()) {
                    fd.addData("menuid", menu2_id).addData("title", titles);
                    fd.addData("init", "sec_" + menu2_id);
                }
                TreeNode node2 = TreeNode.newNode("sec_" + menu2_id).setTitle("<span class=\"menusecond\">" + menu2_name + "</span>").addDatas("grade", 2).setSpread(false)
                        .addDatas("grade", 2).addDatas("titles", titles).addDatas("menuid", menu2_id).setTurn(true);
                node2.setChecked(false);
                if (role_id != null && menu2_role.indexOf("|" + role_id + "|") > -1) {
                    //   node2.setChecked(true);
                }
                List<SysMenu> thirdlist = SysMenuCache.getThirdMenuList(menu2_id);
                for (SysMenu thirds : thirdlist) {
                    int menu3_id = thirds.mod.getInt("menu_id");
                    String menu3_role = "|" + thirds.mod.getStr("menu_role") + "|";
                    String menu3_name = thirds.mod.getStr("menu_name");
                    titles = menu_name + " / " + menu2_name + " / " + menu3_name;
                    TreeNode node3 = TreeNode.newNode("third_" + menu3_id).setTitle("<span class=\"menuthird\">" + menu3_name + "</span>").addDatas("titles", titles).addDatas("grade", 3).addDatas("menuid", menu3_id).setTurn(true);
                    node3.setChecked(false);
                    if (role_id != null && menu3_role.indexOf("|" + role_id + "|") > -1) {
                        node3.setChecked(true);
                    }
                    node2.addChildren(node3);
                }
                node1.addChildren(node2);
            }
            treelist.add(node1);
        }


        fd.addData("tree", JSON.toJSON(treelist));
        //////////////////////////////////////////////////////////////////
        return fd;
    }


    /**
     * 取得菜单树数据
     */
    public FormData getMenuAuthorTreeData(String role_id) {
        FormData fd = FormData.dao();
        /////////////////////////////////////////
        List firstlist = SysMenuCache.getFirstMenuList();
        List treelist = new ArrayList();

        for (int k = 0; k < firstlist.size(); k++) {
            SysMenu first = (SysMenu) firstlist.get(k);
            int menu_id = first.mod.getInt("menu_id");
            String menu_name = first.mod.getStr("menu_name");
            String menu_role = "|" + first.mod.getStr("menu_role") + "|";
            List<SysMenu> seclist = SysMenuCache.getSecondMenuList(menu_id);
            String titles = menu_name;
            if (role_id != null && menu_role.indexOf("|" + role_id + "|") > -1) {
                TreeNode node1 = TreeNode.newNode("first_" + menu_id).setTitle("<span class=\"menufirst\">" + menu_name + "</span>").addDatas("grade", 1)
                        .addDatas("titles", titles).addDatas("menuid", menu_id).setTurn(false).setSpread(true);
                if (k == 0) node1.setSpread(true);
                for (int m = 0; m < seclist.size(); m++) {
                    SysMenu second = (SysMenu) seclist.get(m);
                    int menu2_id = second.mod.getInt("menu_id");
                    String menu2_role = "|" + second.mod.getStr("menu_role") + "|";
                    String menu2_name = second.mod.getStr("menu_name");
                    titles = menu_name + " / " + menu2_name;
                    if (role_id != null && menu2_role.indexOf("|" + role_id + "|") > -1) {
                        TreeNode node2 = TreeNode.newNode("sec_" + menu2_id).setTitle("<span class=\"menusecond\">" + menu2_name + "</span>").addDatas("grade", 2).setSpread(false)
                                .addDatas("grade", 2).addDatas("titles", titles).addDatas("menuid", menu2_id).setTurn(false);
                        List<SysMenu> thirdlist = SysMenuCache.getThirdMenuList(menu2_id);
                        for (SysMenu thirds : thirdlist) {
                            int menu3_id = thirds.mod.getInt("menu_id");
                            String menu3_role = "|" + thirds.mod.getStr("menu_role") + "|";
                            String menu3_name = thirds.mod.getStr("menu_name");
                            titles = menu_name + " / " + menu2_name + " / " + menu3_name;
                            if (role_id != null && menu3_role.indexOf("|" + role_id + "|") > -1) {
                                if (fd.data.isEmpty()) {
                                    fd.addData("menuid", menu3_id).addData("title", titles);
                                    fd.addData("init", "third_" + menu2_id);
                                }
                                TreeNode node3 = TreeNode.newNode("third_" + menu3_id).setTitle("<span class=\"menuthird\">" + menu3_name + "</span>").addDatas("titles", titles).addDatas("grade", 3).addDatas("menuid", menu3_id).setTurn(true);
                                node2.addChildren(node3);
                            }
                        }
                        node1.addChildren(node2);
                    }
                }
                treelist.add(node1);
            }
        }


        fd.addData("tree", JSON.toJSON(treelist));
        //////////////////////////////////////////////////////////////////
        return fd;
    }


    /**
     * 取得菜单树数据
     */
    public FormData getUserMenuAuthorTreeData(int emp_id) {
        FormData fd = FormData.dao();
        String user_roles = SysUserUtil.n().getUserRoleString(emp_id);
        System.out.println(emp_id);
        System.out.println(user_roles);
        /////////////////////////////////////////
        List firstlist = SysMenuCache.getFirstMenuList();
        List treelist = new ArrayList();

        for (int k = 0; k < firstlist.size(); k++) {
            SysMenu first = (SysMenu) firstlist.get(k);
            int menu_id = first.mod.getInt("menu_id");
            String menu_name = first.mod.getStr("menu_name");
            String menu_role = "|" + first.mod.getStr("menu_role") + "|";
            List<SysMenu> seclist = SysMenuCache.getSecondMenuList(menu_id);
            String titles = menu_name;
            if (hasRole(user_roles, menu_role)) {
                TreeNode node1 = TreeNode.newNode("first_" + menu_id).setTitle("<span class=\"menufirst\">" + menu_name + "</span>").addDatas("grade", 1)
                        .addDatas("titles", titles).addDatas("menuid", menu_id).setTurn(false).setSpread(true);
                if (k == 0) node1.setSpread(true);
                for (int m = 0; m < seclist.size(); m++) {
                    SysMenu second = (SysMenu) seclist.get(m);
                    int menu2_id = second.mod.getInt("menu_id");
                    String menu2_role = "|" + second.mod.getStr("menu_role") + "|";
                    String menu2_name = second.mod.getStr("menu_name");
                    titles = menu_name + " / " + menu2_name;
                    if (hasRole(user_roles, menu2_role)) {
                        TreeNode node2 = TreeNode.newNode("sec_" + menu2_id).setTitle("<span class=\"menusecond\">" + menu2_name + "</span>").addDatas("grade", 2).setSpread(false)
                                .addDatas("grade", 2).addDatas("titles", titles).addDatas("menuid", menu2_id).setTurn(false);
                        List<SysMenu> thirdlist = SysMenuCache.getThirdMenuList(menu2_id);
                        for (SysMenu thirds : thirdlist) {
                            int menu3_id = thirds.mod.getInt("menu_id");
                            String menu3_role = "|" + thirds.mod.getStr("menu_role") + "|";
                            String menu3_name = thirds.mod.getStr("menu_name");
                            titles = menu_name + " / " + menu2_name + " / " + menu3_name;
                            if (hasRole(user_roles, menu3_role)) {
                                if (fd.data.isEmpty()) {
                                    fd.addData("menuid", menu3_id).addData("title", titles);
                                    fd.addData("init", "third_" + menu2_id);
                                }
                                TreeNode node3 = TreeNode.newNode("third_" + menu3_id).setTitle("<span class=\"menuthird\">" + menu3_name + "</span>").addDatas("titles", titles).addDatas("grade", 3).addDatas("menuid", menu3_id).setTurn(true);
                                node2.addChildren(node3);
                            }
                        }
                        node1.addChildren(node2);
                    }
                }
                treelist.add(node1);
            }
        }


        fd.addData("tree", JSON.toJSON(treelist));
        //////////////////////////////////////////////////////////////////
        return fd;
    }

    /**
     * 取得当前菜单下的活动ID 字府串
     *
     * @param menu_id
     * @return
     */
    public String getMenuActivityString(int menu_id) {
        StringBuffer sb = new StringBuffer("|");
        List<SysActivity> actlist = SysActivity.dao.find("select * from sys_menu_activity where menu_id=?", menu_id);
        for (SysActivity sa : actlist) {
            sb.append(sa.getInt("act_id") + "|");
        }
        return sb.toString();
    }

    /**
     * 取得用户有权限的一级菜单列表
     *
     * @param roles
     * @param emp_id
     * @return
     */
    public List getUserFirstAuthMenuList(String roles, int emp_id) {
        return getUserAuthMenuList(1, 0, roles, emp_id);
    }

    /**
     * 取得用户有权限的一级菜单列表
     *
     * @param roles
     * @param emp_id
     * @return
     */
    public List getUserSecondAuthMenuList(int pmenuid, String roles, int emp_id) {
        return getUserAuthMenuList(2, pmenuid, roles, emp_id);
    }


    /**
     * 取得用户有权限的一级菜单列表
     *
     * @param roles
     * @param emp_id
     * @return
     */
    public List getUserThirdAuthMenuList(int pmenuid, String roles, int emp_id) {
        return getUserAuthMenuList(3, pmenuid, roles, emp_id);
    }

    /**
     * 取得用户有权限的一级菜单列表
     *
     * @param roles
     * @param emp_id
     * @return
     */
    public List getUserAuthMenuList(int grade, int pmenuid, String roles, int emp_id) {
        if (roles == null) roles = "";
        List mylist = new ArrayList();
        List<SysMenu> menulist = null;
        if (grade == 1) {
            menulist = SysMenuCache.getFirstMenuList();
        } else if (grade == 2) {
            menulist = SysMenuCache.getSecondMenuList(pmenuid);
        } else if (grade == 3) {
            menulist = SysMenuCache.getThirdMenuList(pmenuid);
        } else {
            return mylist;
        }
        String[] rolestr = StrUtil.splitToArray(roles, "|");
        for (SysMenu menu : menulist) {
            boolean hasrole = false;
            String menu_role = "|" + menu.mod.getStr("menu_role", "") + "|";
            String menu_user = "|" + menu.mod.getStr("menu_user", "") + "|";
            for (String role : rolestr) {
                if (!hasrole && role != null && role.length() > 0 && (menu_role.indexOf("|" + role + "|") > -1)) {
                    mylist.add(menu);
                    hasrole = true;
                }
            }
            if (!hasrole && menu_user.indexOf("|" + emp_id + "|") > -1) {
                mylist.add(menu);
            }
        }
        return mylist;
    }

    /**
     * 取得用户有权限的菜单 html
     *
     * @param roles
     * @param emp_id
     * @return
     */
    public String getUserMenuHtml(String roles, int emp_id) {
        StringBuffer sb = new StringBuffer();
        List<SysMenu> firstlist = getUserFirstAuthMenuList(roles, emp_id);
        for (int index = 0; index < firstlist.size(); index++) {
            SysMenu firstmenu = firstlist.get(index);
            int first_menu_id = firstmenu.mod.getInt("menu_id");
            String first_menu_name = firstmenu.mod.getStr("menu_name");
            String menu_icon = firstmenu.mod.getStr("menu_icon");
            ////////////////////////first////////////////////////////////
            sb.append("<li data-name=\"" + first_menu_id + "\" class=\"layui-nav-item " + (index == 0 ? "layui-nav-itemed" : "") + "\">\n" +
                    "    <a href=\"javascript:;\" lay-tips=\"" + first_menu_name + "\" lay-direction=\"2\">\n" +
                    "        <i class=\"layui-icon " + menu_icon + "\"></i>\n" +
                    "        <cite>" + first_menu_name + "</cite>\n" +
                    "    </a>");
            ////////////////////////////////////////////////////////////
            List<SysMenu> seclist = getUserSecondAuthMenuList(first_menu_id, roles, emp_id);
            for (int i = 0; i < seclist.size(); i++) {
                SysMenu secmenu = seclist.get(i);

                int sec_menu_id = secmenu.mod.getInt("menu_id");
                String sec_menu_name = secmenu.mod.getStr("menu_name");
                /////////////////////second/////////////////////////////
                sb.append(" <dl class=\"layui-nav-child\">\n" +
                        "        <dd data-name=\"grid\" class=\"" + (i == 0 && index == 0 ? "layui-nav-itemed" : "") + "\">\n" +
                        "            <a href=\"javascript:;\" class=\"menu1\">" + sec_menu_name + "</a>\n" +
                        "            <dl class=\"layui-nav-child\">");
                ///////////////////////////
                List<SysMenu> thirdlist = getUserThirdAuthMenuList(sec_menu_id, roles, emp_id);
                for (SysMenu thirdmenu : thirdlist) {
                    String third_menu_name = thirdmenu.mod.getStr("menu_name");
                    String third_menu_path = thirdmenu.mod.getStr("menu_path");
                    third_menu_path = StringUtil.replace(third_menu_path, "[path]/", "");
                    /////////////////third///////////////////////////////
                    sb.append("<dd data-name=\"list\"><a class=\"menu2\" lay-href=\"" + third_menu_path + "\">" + third_menu_name + "</a></dd>\n");
                }
                /////////////second////////////
                sb.append("\n</dl>");
                sb.append("\n</dd>");
                sb.append("\n</dl>");
                /////////////////////////
            }
            ///////////first///////////////////////
            sb.append("\n</li>");
            /////////////////////////////////////
        }
        return sb.toString();
    }

    /**
     * 查看用户是否属于角色
     *
     * @param userRole
     * @param roles
     * @return
     */
    public boolean hasRole(String userRole, String roles) {
        roles = StrUtil.replace(roles, ",", "|");
        roles = StrUtil.addPrefixIfNot(roles, "|");
        roles = StrUtil.addSuffixIfNot(roles, "|");
        userRole = StrUtil.replace(userRole, ",", "|");
        String[] userRoleList = StrUtil.splitToArray(userRole, "|");
        for (String role : userRoleList) {
            if (StrUtil.contains(roles, "|" + role + "|")) {
                return true;
            }
        }
        return false;
    }
}
